#include <string>
#include "operatorunary.h"
#include "node.h"
#include "type.h"

// Tratamento de Erro
extern void yyerror(const char*);

namespace AST {

    // Construtor Padrão
    OperatorUnary::OperatorUnary(std::string* content, Node* operand) {
        // Configuração Inicial
        this->_setContent(content)->_setOperand(operand);
    };

    // Configuração de Conteúdo
    OperatorUnary* OperatorUnary::_setContent(std::string* content) {
        // Configuração
        this->_content = content;
        // Encadeamento
        return this;
    };

    // Operando Utilizado
    OperatorUnary* OperatorUnary::_setOperand(Node* operand) {
        // Configuração
        this->_operand = operand;
        // Encadeamento
        return this;
    };

    // Apresentação de Conteúdo
    std::string* OperatorUnary::getContent() {
        // Apresentação
        return this->_content;
    };

    // Apresentação de Operando
    Node* OperatorUnary::getOperand() {
        // Apresentação
        return this->_operand;
    };

    // Sobrescrita
    std::string OperatorUnary::toString(int indent) {
        // Apresentação
        return this->getIndentSpaces(indent)
            + "Operator '" + (*this->getContent()) + "'\n"
            + this->getOperand()->toString(indent + 1);
    };

    // Sobrescrita
    Node* OperatorUnary::check() {
        // Tipo Interno da Expressão
        Type* type = this->getOperand()->getType();
        // Não Aceitar Conjunto de Dados
        if (type->getIsArray()) {
            // Erro Encontrado
            yyerror("OperatorUnary > Array");
        }
        // Verificação
        switch (type->getContent()) {
            // Inteiro
            case AST::Type::INTEGER:
                // Inversor Aritmético e Lógico
                this->setType(new AST::Type(AST::Type::INTEGER));
                break;
            // Ponto Flutuante
            case AST::Type::FLOAT:
                // Somente Inversor Aritmético Aceito
                if ((*this->getContent()) != "-") {
                    // Erro Encontrado
                    yyerror("OperatorUnary > Float");
                }
                // Inversor Aritmético
                this->setType(new AST::Type(AST::Type::FLOAT));
                break;
            default:
                // Erro Encontrado
                yyerror("OperatorUnary > Unknown");
                break;
        }
        // Encadeamento
        return this;
    };

};

